#include "PrivateProtocol.h"
#include "Util/util.h"
#include "Common/MediaSourceCacheCenter.h"

namespace privateproto {
    
    bool DeviceChannel::parse_streamid(const std::string &stream_id) {
        auto arrs = toolkit::split(stream_id,"_");
        _partcount = (int)arrs.size();
        if(_partcount >= 3) {
            if(_partcount == 3) {//没有schema
                _deviceid = arrs[0];
                _channelid = arrs[1];
                _ssrc = arrs[2];
            }else{
                _schema = arrs[0];
                _deviceid = arrs[1];
                _channelid = arrs[2];
                _ssrc = arrs[3];
            }
            return true;
        }else{
             return false;
        }
    }
    
    bool DeviceChannel::is_playback() const{
        return _ssrc.length() > 1 && _ssrc[0] == '1';
    }
    
    bool CheckPlayBackStreamFromStreamId(const std::string stream_id) {
         auto arrs = toolkit::split(stream_id,"_");
         if(arrs.size() == 4 && arrs[3][0] == '1') {//master分支上SSRC以1开头是回放流,但master分支上是以9开头的是回放流
             return true;
         }else if(arrs.size() == 3 && arrs[2][0] == '1') {//福州分支上SSRC以1开头是回放流,但master分支上是以9开头的是回放流
             return true;
         }else{
             return false;
        }
    }
    bool CheckCacheStreamFromStreamId(const std::string stream_id) {
         auto arrs = toolkit::split(stream_id,"_");
         if(arrs.size() == 4 && arrs[0].compare("cache") == 0) {
             return true;
         }else{
             if(arrs.size() == 3) {
                 return true;
             }else{
                 return false;
            }
        }
    }
    void CheckCacheHit(const std::string stream_id, time_t starttime, time_t endtime,std::function<void(bool ,const std::string ,const std::string )> cb) {

        DeviceChannel dev_chan;
        if(!dev_chan.parse_streamid(stream_id)) {
            cb(false,stream_id,stream_id);
            //printf("[%s:%d]%s\n",__FUNCTION__,__LINE__,dev_chan.ToString().c_str());
            return;
        }
        if(!dev_chan.is_playback()){//只在回放的时候才考虑命中缓存
            cb(false,stream_id,stream_id);
            //printf("[%s:%d]%s\n",__FUNCTION__,__LINE__,dev_chan.ToString().c_str());
            return;
        }
        DeviceRecordCache::Ptr _cacher = MediaSourceCacheCenter::Instance().GetRecordCacher(dev_chan, false, false);
        if(!_cacher) {
            cb(false,stream_id,stream_id);
            //printf("[%s:%d]%s\n",__FUNCTION__,__LINE__,dev_chan.ToString().c_str());
            return;
        }
        //printf("[%s:%d]%s\n",__FUNCTION__,__LINE__,dev_chan.ToString().c_str());
        _cacher->play_record_resources(dev_chan, starttime,endtime,[=](bool bhitcache,const std::string old_stream_id,const std::string new_stream_id){
            //检索设备通道缓存结果回调
            cb(bhitcache,old_stream_id,new_stream_id);
        });
    }
    void CloseCacheSubscriber(const std::string stream_id){
        DeviceChannel dev_chan;
        if(!dev_chan.parse_streamid(stream_id)) {
            return;
        }
        DeviceRecordCache::Ptr _cacher = MediaSourceCacheCenter::Instance().GetRecordCacher(dev_chan, false, false);
        if(!_cacher) {
            return;
        }
        _cacher->close_cache_stream_subscriber(dev_chan);
    }
    
    void ControlCacheStream(const std::string stream_id, const std::string command, const float scale,std::function<void(bool controlsuccess)> cb) {
        DeviceChannel dev_chan;
        if(!dev_chan.parse_streamid(stream_id)) {
            cb(false);
            return;
        }
        DeviceRecordCache::Ptr _cacher = MediaSourceCacheCenter::Instance().GetRecordCacher(dev_chan, false, false);
        if(!_cacher) {
            cb(false);
            return;
        }
        _cacher->control_cache_stream(dev_chan, command,scale,[cb](bool controlsuccess){
            //检索设备通道缓存结果回调
            cb(controlsuccess);
        });
    }
    void CloseCacheStreamSubscriber(const std::string stream_id) {
        DeviceChannel dev_chan;
        if(!dev_chan.parse_streamid(stream_id)) {
            return;
        }
        DeviceRecordCache::Ptr _cacher = MediaSourceCacheCenter::Instance().GetRecordCacher(dev_chan, false, false);
        if(!_cacher) {
            return;
        }
        _cacher->close_cache_stream_subscriber(dev_chan);
    }
    bool IsBrokenTimestamp(uint32_t timestamp, uint32_t prev_timestamp){
    //     return timestamp != prev_timestamp &&((uint32_t) (timestamp - prev_timestamp)) > 1000;
        return labs((int64_t)timestamp-(int64_t)prev_timestamp) > 1000L;
    }
}
